from moviepy.editor import *
import random
import argparse
import uuid
import os
from groupswap import GSwap
# this is not the best audio mixing platform. this sucks.

sysrand = random.SystemRandom()
prefix = str(uuid.uuid4())+"_"
timestamp = "_"+str(time.time())
# getting main width first.
# deliver a general solution.
# generate metadata accordingly? better not.
def zoom(clip, factor):
    c = (1-1.0/factor) / 2
    x_crop = int(c * clip.w)
    y_crop = int(c * clip.h)
    return clip.crop(x_crop, y_crop, -x_crop, -y_crop).resize(clip.size)

#newclip = clip.fx(zoom, factor=2)
def minmax(_min,_max):
    assert _max>_min
    _range = _max-_min
    return sysrand.random()*_range+_min

def toInvert(clip,factor):
    if factor>1:
        return clip.invert_colors()
    return clip
# shall it be executed here.
cliplocation = "../collector/video_download/bilibili_video/{}/{}.flv".format(token,token)
assert os.path.exists(cliplocation)
assert os.path.isfile(cliplocation)
main_title = prefix+main_title+timestamp
outputlocation = "video_output/{}.mp4".format(main_title)
tempaudiolocation = "audio_output/{}TEMP_MPY_wvf_snd.mp3".format(main_title)
finallocation = "video_output/{}_final.mp4".format(main_title)
clip = VideoFileClip(cliplocation)
zoomfactor = 1.5
#print(clip.duration)
#width, height = clip.
duration = clip.duration
abs_end = clip.duration
_min, _max = 0.4,1.5
_minvol, _maxvol = 0.8, 1.3
_minfps, _maxfps = 0.5, 2.0
_minRotate, _maxRotate = -0.2, 0.2
granulizer = 2
grans=[]
# every 2 seconds. or around.
while duration>granulizer:
    durs = minmax(_min,_max)*granulizer
    grans.append(durs)
    duration -= durs
grans.append(duration)

accum = 0
abnormal = True
lgrans = len(grans)
lshuf = list(range(lgrans))
lshuf = GSwap(lshuf,2).operate()
clips = []
for factor in range(lgrans):
    print("processing clip",factor,"total",lgrans)
    gfact = grans[factor]
    end = accum + gfact 
    if end > abs_end or factor == (lgrans-1):
        end = abs_end
    start = accum
    if start > end:
        abnormal = True
        break
    accum = end
    # the cropping shall be in the end?
#    subclip = clip.subclip(start,end)
#    subclip = subclip.volumex(minmax(_minvol,_maxvol)
#    subclip = subclip.speedx(minmax(_minfps,_maxfps)
    clips.append(toInvert(clip.subclip(start,end).volumex(minmax(_minvol,_maxvol)).rotate(30*minmax(_minRotate,_maxRotate)),minmax(0.2,1.2)).fx(zoom,factor=zoomfactor))
print("concatinating")
if abnormal:
    lgrans = len(clips)
    lshuf = list(range(lgrans))
    lshuf = GSwap(lshuf,2).operate()
video = concatenate_videoclips([clips[x] for x in lshuf],method="compose")
#video.resize((1920,1080))
#video.resize(zoom)
#video.fx(zoom,factor=zoomfactor)
# what the fuck?
print("writing output to",outputlocation)
video.write_videofile(outputlocation,codec="libx264",audio=True,temp_audiofile=tempaudiolocation,remove_temp=False)
import subprocess as sp
command = ['ffmpeg',
           '-y', #approve output file overwite
           '-i', str(outputlocation),
           '-i', str(tempaudiolocation),
           '-c:v', 'copy',
           '-c:a', 'copy',
           '-shortest', 
           str(finallocation) ]
ffmpeg_log = "ffmpeg.log"
with open(ffmpeg_log, 'a+') as f:
    process = sp.Popen(command, stderr=f)
process.communicate()
os.remove(outputlocation)
os.remove(tempaudiolocation)
# wrong argument.
print("done")
# shuffle the shit.
